package com.feiyue.learning.advance.nio;

import java.io.File;
import java.io.FileInputStream;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;

public class NioSendClient {

    private static final Charset charset = Charset.forName("UTF-8");
    private static final String SRC_PATH = "C:\\Users\\zhou.xm\\Desktop\\get.json";
    private static final String DEST_FILE_NAME = "dest.json";

    public static void main(String[] args) throws Exception {
        NioSendClient client = new NioSendClient();

        // 传输文件
        client.sendFile();
    }

    private void sendFile() throws Exception {
        File file = new File(SRC_PATH);
        if (!file.exists()) {
            System.out.println("文件不存在");
            return;
        }

        FileInputStream fis = new FileInputStream(SRC_PATH);
        FileChannel inChannel = fis.getChannel();
        SocketChannel socketChannel = SocketChannel.open();
        socketChannel.socket().connect(new InetSocketAddress("127.0.0.1", 80));

        // 设置非阻塞模式，不断轮询检查当前主机是否连接服务器
        socketChannel.configureBlocking(false);
        while (! socketChannel.finishConnect()) {
            // 不断自旋、等待
        }
        System.out.println("连接服务器成功");

        // 发送文件名称, charset.encode(String) 生成的 Buffer 已经包含 String 中的内容, 可以直接进行读取
        ByteBuffer fileNameByteBuffer = charset.encode(DEST_FILE_NAME);
        socketChannel.write(fileNameByteBuffer);

        // 发送文件长度
        ByteBuffer sizBuffer = ByteBuffer.allocate(1024);
        sizBuffer.putLong(file.length());
        sizBuffer.flip();
        socketChannel.write(sizBuffer);

        // 发送文件内容
        System.out.println("开始传输文件：");
        int length;
        long progress = 0;
        sizBuffer.clear();
        while ((length = inChannel.read(sizBuffer)) > 0) {
            sizBuffer.flip();
            socketChannel.write(sizBuffer);
            sizBuffer.clear();
            progress += length;
            System.out.println("传输进度：| " + (100 * progress / file.length()) + "% |");
        }

        if (length == -1) {
            inChannel.close();

            // 向服务器发送终止输出的标识（-1）
            socketChannel.shutdownOutput();
            socketChannel.close();
        }
        System.out.println("文件传输完成");
    }
}
